package logic

import (
	"context"
	"errors"

	"wxapi/internal/services"
	"wxapi/internal/svc"
	"wxapi/internal/types"
	"wxapi/models"

	"github.com/shopspring/decimal"
	"github.com/zeromicro/go-zero/core/logx"
)

type CreateOrderLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateOrderLogic {
	return &CreateOrderLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq) (resp *types.CreateOrderResp, err error) {
	userId, err := services.GetUserIdBySession(l.ctx, l.svcCtx, req.Session)
	if err != nil {
		return nil, err
	}

	user, err := services.GetUserById(l.ctx, l.svcCtx, userId)
	if err != nil {
		return nil, err
	}

	payType, err := services.GetPayTypeById(l.ctx, l.svcCtx, req.PayType)
	if err != nil {
		return nil, err

	}

	goods, err := services.GetCarGoods(l.ctx, l.svcCtx, user.ID)
	if err != nil {
		return nil, err
	}
	if len(goods) == 0 {
		return nil, errors.New("请先选择项目")
	}
	storeIdMap := make(map[int64]bool)
	for _, item := range goods {
		storeIdMap[item.StoreId] = true
	}
	if len(storeIdMap) > 1 {
		return nil, errors.New("只能选择一个商家下单")
	}

	amount := decimal.NewFromFloat(0.0)
	for _, v := range goods {
		amount = amount.Add(v.Skill.Price)
	}

	totalAmount := amount
	if user.Member != nil && user.Member.Level != nil && user.Member.Level.Discount != nil {
		discount := user.Member.Level.Discount.Discount.Div(decimal.NewFromFloat(10.0))
		totalAmount = totalAmount.Mul(discount)
	}

	order := &models.Orders{
		UserId:             user.ID,
		StoreId:            goods[0].StoreId,
		OrderSn:            services.CreateOrderSn(l.ctx, l.svcCtx),
		State:              10,
		ProductCouont:      int64(len(goods)),
		ProductAmountTotal: amount.InexactFloat64(),
		OrderAmountTotal:   totalAmount.InexactFloat64(),
		PayChannel:         payType.Abbr,
		Notes:              req.Notes,
		Items:              make([]*models.OrderItems, 0),
		Discount: &models.OrderDiscount{
			UserId:   user.ID,
			MemberId: user.Member.ID,
			Discount: user.Member.Level.Discount.Discount,
		},
	}

	for _, v := range goods {
		order.Items = append(order.Items, &models.OrderItems{
			StoreId:     v.StoreId,
			DoctorId:    v.DoctorId,
			SkillId:     v.Skill.ID,
			BeginTime:   v.BeginTime,
			Duration:    v.Skill.Duration,
			Price:       v.Skill.Price,
			Count:       1,
			AmountTotal: v.Skill.Price.InexactFloat64(),
		})
	}

	err = services.CreateOrder(l.ctx, l.svcCtx, order)
	if err != nil {
		return nil, err
	}
	err = services.ClearCar(l.ctx, l.svcCtx, user.ID)
	if err != nil {
		return nil, err
	}
	resp = &types.CreateOrderResp{
		OrderSn: order.OrderSn,
		Amount:  totalAmount.InexactFloat64(),
	}

	return
}
